package com.gmics.unifiq.controller;

import org.apache.http.client.HttpResponseException;

import android.os.StrictMode;
import android.util.Log;

import com.gmics.unifiq.entity.PlaceDetails;
import com.gmics.unifiq.entity.PlaceList;
import com.google.android.gms.maps.model.LatLng;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonObjectParser;
import com.google.api.client.json.jackson.JacksonFactory;

@SuppressWarnings("deprecation")
public class GooglePlace {

	/** Global instance of the HTTP transport. */
	private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();

	// Google API Key
	private static final String API_KEY = "AIzaSyDQ-1WOW-OyqAxEHGlce35lP4m2Zh6TtX4";
	//private static final String API_KEY = "AIzaSyC682DbFdSXuRvIpUoSH370T-cR8PdO7wI";
	//private static final String API_KEY = "AIzaSyAfzcq2wakggaEESd7mgv6VB84Ir_obnIk";
	
	// Google Places serach url's
	private static final String PLACES_SEARCH_URL = "https://maps.googleapis.com/maps/api/place/search/json?";
	private static final String PLACES_TEXT_SEARCH_URL = "https://maps.googleapis.com/maps/api/place/textsearch/json?";
	private static final String PLACES_RADAR_SEARCH_URL = "https://maps.googleapis.com/maps/api/place/radarsearch/json?";
	private static final String PLACES_DETAILS_URL = "https://maps.googleapis.com/maps/api/place/details/json?";
	private static final String PLACES_REVERSE_GEOCODE_URL = "http://maps.googleapis.com/maps/api/geocode/json?";
	
	private double nearbyRadius = 1000, radarRadius = 10000; 
	private static final LatLng SINGAPORE = new LatLng(1.368123, 103.798981);
	
	/**
	 * Creating http request Factory
	 * */
	public static HttpRequestFactory createRequestFactory(
			final HttpTransport transport) {
		return transport.createRequestFactory(new HttpRequestInitializer() {
			@Override
			public void initialize(HttpRequest request) {
				HttpHeaders headers = new HttpHeaders();
				headers.setUserAgent("AndroidHive-Places-Test");
				request.setHeaders(headers);
				JsonObjectParser parser = new JsonObjectParser(
						new JacksonFactory());
				request.setParser(parser);
			}
		});
	}
	
	/**
	 * Searching single place full details
	 * 
	 * @param refrence
	 *            - reference id of place - which you will get in search api
	 *            request
	 * */
	public PlaceDetails getPlaceDetails(String reference) throws Exception {
		setStrictMode();
		
		try {

			HttpRequestFactory httpRequestFactory = createRequestFactory(HTTP_TRANSPORT);
			HttpRequest request = httpRequestFactory
					.buildGetRequest(new GenericUrl(PLACES_DETAILS_URL));
			request.getUrl().put("key", API_KEY);
			request.getUrl().put("reference", reference);
			request.getUrl().put("sensor", "false");

			PlaceDetails place = request.execute().parseAs(PlaceDetails.class);

			return place;

		} catch (HttpResponseException e) {
			Log.e("Error in Perform Details", e.getMessage());
			throw e;
		}
	}

	public PlaceList radarSearch(String[] types) throws Exception {	
		String type = null;
		
		if (types.length > 1){
			for (int i = 0; i < types.length; i++){
				if (i == 0){
					type = types[i];
				}
				else{
					type += "|" + types[i];
				}
			}
		}
		else{
			type = types[0];
		}
		
        try {
            HttpRequestFactory httpRequestFactory = createRequestFactory(HTTP_TRANSPORT);
            HttpRequest request = httpRequestFactory
                    .buildGetRequest(new GenericUrl(PLACES_RADAR_SEARCH_URL));
            request.getUrl().put("key", API_KEY);
            request.getUrl().put("location", SINGAPORE.latitude + "," + SINGAPORE.longitude);
            request.getUrl().put("radius", radarRadius); // in meters
            request.getUrl().put("sensor", "false");
            if (type != null)
            	request.getUrl().put("types", type);
            
            Log.d("request url", request.getUrl().toString());
            PlaceList list = request.execute().parseAs(PlaceList.class);
            // Check log cat for places response status
            Log.d("Places Status", "" + list.status);
            return list;
 
        } catch (HttpResponseException e) {
            Log.e("Error:", e.getMessage());
            return null;
        }
	}

	public PlaceList reverseGeocode(double latitude, double longitude) throws Exception {

		setStrictMode();
		
		try{
			HttpRequestFactory httpRequestFactory = createRequestFactory(HTTP_TRANSPORT);
			HttpRequest request = httpRequestFactory
					.buildGetRequest(new GenericUrl(PLACES_REVERSE_GEOCODE_URL));
			request.getUrl().put("key", API_KEY);
			request.getUrl().put("location", latitude + "," + longitude);
			request.getUrl().put("sensor", "false");
			PlaceList list = request.execute().parseAs(PlaceList.class);
			// Check log cat for places response status
			Log.d("Places Status", "" + list.status);
			return list;

		} catch (HttpResponseException e) {
			Log.e("Error:", e.getMessage());
			return null;
		}

	}
	
	/**
	 * Searching places
	 * 
	 * @param latitude
	 *            - latitude of place
	 * @params longitude - longitude of place
	 * @param radius
	 *            - radius of searchable area
	 * @param types
	 *            - type of place to search
	 * @return list of places
	 * */
	public PlaceList search(double latitude, double longitude,
			String types) throws Exception {
		
        try {
        	 
            HttpRequestFactory httpRequestFactory = createRequestFactory(HTTP_TRANSPORT);
            HttpRequest request = httpRequestFactory
                    .buildGetRequest(new GenericUrl(PLACES_SEARCH_URL));
            request.getUrl().put("key", API_KEY);
            request.getUrl().put("location", latitude + "," + longitude);
            request.getUrl().put("radius", nearbyRadius); // in meters
            request.getUrl().put("sensor", "false");
            if(types != null)
                request.getUrl().put("types", types);
 
            PlaceList list = request.execute().parseAs(PlaceList.class);
            // Check log cat for places response status
            Log.d("Places Status", "" + list.status);
            return list;
 
        } catch (HttpResponseException e) {
            Log.e("Error:", e.getMessage());
            return null;
        }

	}

	public void setStrictMode(){
		if (android.os.Build.VERSION.SDK_INT > 9) {
			StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
					.permitAll().build();
			StrictMode.setThreadPolicy(policy);
		}
	}
}
